package cate.game.role.pvp.throne;

import cate.common.table.d.GDFight;
import cate.common.table.d.GDObj;
import cate.common.table.d.GDOperation;
import cate.common.table.d.GDThrone;
import cate.game.pvp.throne.data.ko.TBKoBet;
import cate.game.pvp.throne.data.ko.TBKoCurBet;
import cate.game.pvp.throne.data.ko.TBKoTimeTable;
import cate.game.res.MixRes;
import cate.game.res.MixResAdder;
import cate.game.res.MixResItem;
import cate.game.role.Role;
import cate.game.role.RoleDependent;
import cate.game.role.pvp.throne.msg.RoleTBKoResp;
import cate.game.role.pvp.throne.msg.TBKoCurBetUpdate;
import com.fasterxml.jackson.annotation.JsonIgnore;
import easy.java.dev.note.NoteClass;
import easy.java.dev.note.NoteField;
import easy.java.practice.errorcode.EcResult;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@NoteClass("王座争霸淘汰赛数据")
public class RoleTBKO extends RoleDependent {

	@NoteField(value = "历史最高排名",detail = "Map<等级组,排名>")
	public Map<Integer, Integer> history;

	@NoteField(value = "领取竞猜币的情况",detail = "Map<回合,领取的币>")
	public Map<Integer,Double> betCoinGot;

	@NoteField("竞猜记录")
	public List<TBBetRecord> betRecords;

	public void initialize(Role role) {
		super.initialize(role);
		if (history == null) {
			history = new HashMap<>();
		}
		if (betCoinGot == null) {
			betCoinGot = new HashMap<>();
		}
		if (betRecords == null) {
			betRecords = new ArrayList<>();
		}
	}

	@Override
	public void onEnter() {
		settleBet(true);
	}

	public void onSeasonChange() {
		betCoinGot.clear();
		betRecords.clear();
	}

	public void recordRank(int levelGroup, int rank) {
		int old = history.getOrDefault(levelGroup, -1);
		if (old > 0 && old < rank) {
			return;
		}
		history.put(levelGroup, rank);
		noticeUpdate();
	}

	public void settleBet(boolean silence) {
		if (!game().pvp.throne.data.isDataReady()) {
			return;
		}
		final Map<Integer, TBKoBet.BetResult> resultMap = game().pvp.throne.data.holder.koBase.bet.resultMap;
		MixRes reward = new MixRes();
		for (TBBetRecord record : betRecords) {
			if (record.winner == GDFight.Team.NONE) {
				TBKoBet.BetResult result = resultMap.get(record.round);
				if (result == null) {
					continue;
				}
				record.winner = result.winner;
				if (record.betTeam == result.winner) {
					record.rwdPoint = (long) (result.odd * record.betCoin * GDThrone.BET_RWD_COEFF);
				} else {
					record.rwdPoint = GDThrone.BET_FAIL_RWD;
				}
				reward.addItem(new MixResItem(GDObj.Type.NUM, GDObj.Num.THRONE_POINT, record.rwdPoint));
			}
		}
		if (!reward.isEmpty()) {
			new MixResAdder().setRes(reward).setOperation(GDOperation.THRONE_BET).setDialogReward(true).exe(role);
		}
		if(!silence){
			noticeUpdate();
		}
	}

	@JsonIgnore
	public EcResult<Void> getBetCoin() {
		EcResult<Void> r = new EcResult<>();
		TBKoTimeTable timeTable = game().pvp.throne.data.holder.koBase.timeTable;
		if (!timeTable.inBet()) {
			return r.fail("当前不是竞猜阶段");
		}
		final int curRound = timeTable.getRound();
		if (betCoinGot.containsKey(curRound)) {
			return r.fail("当前轮次已经领过");
		}
		if (betRecords.size() >= GDThrone.BET_MAX_TIME) {
			return r.fail("竞猜次数达到上限");
		}
		TBKoCurBet curBet = game().pvp.throne.data.holder.koBase.bet.cur;
		if (curBet == null) {
			return r.fail("当前没有竞猜场次");
		}
		betCoinGot.put(curRound, GDThrone.BET_COIN);
		MixRes show = new MixRes();
		show.addItem(new MixResItem(GDObj.Type.NUM, GDObj.Num.TB_BET_COIN, (long) GDThrone.BET_COIN));
		role.getGame().notice.dialogReward(role, show);
		noticeUpdate();
		return r.success();
	}

	public EcResult<Void> betExe(byte betTeam) {
		EcResult<Void> r = new EcResult<>();
		TBKoTimeTable timeTable = game().pvp.throne.data.holder.koBase.timeTable;
		if (!timeTable.inBet()) {
			return r.fail("当前不是竞猜阶段");
		}
		final int curRound = timeTable.getRound();
		if (!betCoinGot.containsKey(curRound)) {
			return r.fail("尚未领取竞王座银币");
		}
		if (betRecords.size() >= GDThrone.BET_MAX_TIME) {
			return r.fail("竞猜次数达到上限");
		}
		TBKoCurBet curBet = game().pvp.throne.data.holder.koBase.bet.cur;
		if (curBet == null) {
			return r.fail("当前没有竞猜场次");
		}
		if (betTeam != GDFight.Team.A && betTeam != GDFight.Team.B) {
			return r.fail("竞猜队伍选择有误");
		}
		boolean hasBet = betRecords.stream().anyMatch(record -> record.round == curRound);
		if (hasBet) {
			return r.fail("已经竞猜过");
		}
		betRecords.add(new TBBetRecord(curBet, betTeam));
		game().pvp.throne.message.koBet(betTeam);
		TBKoCurBetUpdate betUpdate = new TBKoCurBetUpdate(game().pvp.throne.data.holder.koBase.bet.cur);
		betUpdate.send(role);
		noticeUpdate();
		return r.success();
	}

	public void noticeUpdate(){
		role.sendNow(new RoleTBKoResp(this));
	}
}
